package com.otitan.la.forest.system.controller;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.otitan.auth.framework.basepro.common.AuthCommon;
import com.otitan.auth.framework.basepro.config.HasPermission;
import com.otitan.la.forest.system.constant.DicCodeConstant;
import com.otitan.la.forest.system.dto.LoginUserDTO;
import com.otitan.la.forest.system.dto.UserDTO;
import com.otitan.la.forest.system.dto.UserResetDTO;
import com.otitan.la.forest.system.entity.ApplicationEntity;
import com.otitan.la.forest.system.entity.LogEntity;
import com.otitan.la.forest.system.entity.UserEntity;
import com.otitan.la.forest.system.service.LogService;
import com.otitan.la.forest.system.service.UserService;
import com.otitan.la.forest.system.vo.LoginUserAuthVO;
import com.otitan.la.forest.system.vo.LoginVO;
import com.otitan.la.forest.system.vo.UserEntityVO;
import com.otitan.webapp.framework.basepro.model.DataResult;
import io.swagger.annotations.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.SecurityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;
import java.util.ArrayList;
import java.util.List;

/**
 * 用户表
 *
 * @author jiacs
 * @email xxx
 * @date 2020-09-15 16:01:53
 */
@Slf4j
@Api(tags = "用户表API")
@RestController
@RequestMapping("/user")
public class UserController {


    @Autowired
    private UserService userService;

    @Autowired
    private StringRedisTemplate redisTemplate;

    @Autowired
    private AuthCommon authCommon;
    @Autowired
    private LogService logService;

    @Value("${redis.key-prefix}")
    private String redisKeyPrefix;

    @ApiOperation(value = "新增")
    @PostMapping()
    public DataResult add(@Valid @RequestBody UserEntity user, BindingResult bindingResult) {
        return userService.add(user, bindingResult);
    }

    @ApiOperation(value = "批量删除")
    @DeleteMapping("/batchDelete")
    public DataResult batchDelete(@RequestBody @ApiParam(value = "ID集合") List<String> ids) {
        return userService.batchDelete(ids);
    }

    @ApiOperation(value = "删除")
    @DeleteMapping("/delete/{id}")
    public DataResult delete(@PathVariable("id") String id) {
        List<String> ids = new ArrayList<String>() {{
            add(id);
        }};
        return userService.batchDelete(ids);
    }

    @ApiOperation(value = "更新")
    @PutMapping
    public DataResult editor(@Valid @RequestBody UserEntity user, BindingResult bindingResult) {
        return userService.editor(user, bindingResult);
    }

    @ApiOperation(value = "列表查询（分页）")
    @PostMapping("/select/{page}/{size}")
    public DataResult<Page<UserEntityVO>> findPageData(@PathVariable("page") long page,
                                                     @PathVariable("size") long size,
                                                     @RequestBody UserDTO user) {
        return userService.findPageData(page, size, user);
    }

    @ApiOperation(value = "根据ID查询")
    @GetMapping("/findOne/{id}")
    public DataResult<UserEntityVO> findOne(@PathVariable("id") String id) {
        return userService.findOne(id);
    }

    @HasPermission("open")
    @ApiOperation(value = "登录")
    @PostMapping("/login")
    public DataResult<LoginVO> login(@Valid @RequestBody LoginUserDTO dto, BindingResult bindingResult) {
        if (bindingResult.hasErrors()) {
            return DataResult.fail(bindingResult.getFieldError().getDefaultMessage());
        }
        return userService.login(dto);
    }

    @HasPermission("open")
    @ApiOperation(value = "用户注销")
    @GetMapping(value = "/logout")
    public DataResult logout(HttpServletRequest request) {
        try {
            JSONObject user = authCommon.getLoginUserInfo();
            String tokenId = request.getSession().getId();
            redisTemplate.delete(redisKeyPrefix + tokenId);
            if (user != null) {
                redisTemplate.delete(redisKeyPrefix + user.get("userName"));
            }
            SecurityUtils.getSubject().logout();

            // 添加系统日志
            LogEntity logUser=new LogEntity();
            logUser.setAction(DicCodeConstant.LOGIN_OUT);
            logUser.setAppCode(DicCodeConstant.SYSTEM);
            logService.setSystemLogger(logUser, tokenId);

        } catch (Exception e) {
            log.error("退出登录异常，{}", e.getMessage());
        }
        return DataResult.success();
    }

    @GetMapping(value = "/getLoginUserAuth/{appCode}")
    @ApiOperation(value = "获取当前登录用户权限")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "appCode", required = true, value = "应用编码")
    })
    public DataResult<LoginUserAuthVO> getLoginUserAuth(HttpServletRequest request, @PathVariable("appCode") String appCode) {
        return userService.getLoginUserAuth(request, appCode);
    }

    @GetMapping(value = "/getLoginUserApp")
    @ApiOperation(value = "获取当前登录应用权限")
    public DataResult<List<ApplicationEntity>> getLoginUserApp() {
        return userService.getLoginUserApp();
    }

    @GetMapping(value = "/getLoginUserInfo")
    @ApiOperation(value = "获取当前登录用户信息")
    public DataResult<UserEntity> getLoginUserInfo() {
        return userService.getLoginUserInfo();
    }

    /**
     * 重置密码
     *
     * @param
     * @return com.otitan.webapp.framework.basepro.model.DataResult
     * @throws
     * @author Sunke
     * @date 2020/9/27 0027 09:50
     */
    @ApiOperation(value = "重置密码")
    @PostMapping({"/resetPwd/{id}"})
    public DataResult resetPwd(@PathVariable String id) {
        return userService.resetPwd(id);
    }

    /**
     * 用户修改密码
     *
     * @param
     * @return com.otitan.webapp.framework.basepro.model.DataResult
     * @throws
     * @author Sunke
     * @date 2020/9/27 0027 10:21
     */
    @ApiOperation(value = "修改密码")
    @PostMapping({"/updatePwd"})
    public DataResult updatePwd(@Valid @RequestBody UserResetDTO userDTO, BindingResult bindingResult) {
        return userService.updatePwd(userDTO, bindingResult);
    }

}
